#include <burst_kernel.h>

typedef struct {
	uint8_t *str;
	int len;
} bus_arg_t;

typedef struct {
	int argc;
	bus_arg_t *argv;
} bus_arg_table_t;

/*
 * expr: add_expr;
 *
 * add_op: '+' | '-'
 * 
 * add_expr: mul_expr (add_op mul_expr)*;
 *
 * mul_op: '*' | '/' | '%'
 * 
 * mul_expr: factor_expr (mul_op factor_expr)*;
 *
 * factor_expr: number | EOF;
 */

static uint64_t bus_parse_value;

static uint64_t bus_batch_factor()
{
	int token;
	u64 value;
	token = lexer_get_token(&value, 0, 0);
	switch(token) {
	case NUM:
		goto out;
	case NOT:
		value = ~(bus_batch_factor());
		goto out;
	case ADD:
		value = +(bus_batch_factor());
		goto out;
	case SUB:
		value = -(bus_batch_factor());
		goto out;
	case LB:
		value = bus_batch_expr();
		if(lexer_get_token(0, 0, 0) != RB) {
			value = BADTOK;
		}
		goto out;
	}
out:
	return value;
}

static uint64_t bus_batch_mul_op()
{
	int token;
	u8 **string;
	int len;
	u64 value;
	token = lexer_get_token(&value, &string, &len);
	switch(token) {
	case MUL:
		value = MUL;
		goto out;
	case DIV:
		value = DIV;
		goto out;
	default:
		value = BADTOK;
		goto out;
	}
out:
	return value;
}

static uint64_t bus_batch_mul_expr()
{
	int token;
	u64 value;
	value = bus_batch_factor();
	while((token = bus_batch_mul_op()) != BADTOK) {
		if(token == MUL)
			value *= bus_batch_factor();
		if(token == DIV)
			value /= bus_batch_factor();
	}
out:
	return value;
}

static uint64_t bus_batch_add_op()
{
	int token;
	u8 **string;
	int len;
	u64 value;
	token = lexer_get_token(&value, &string, &len);
	switch(token) {
	case ADD:
		value = ADD;
		goto out;
	case SUB:
		value = SUB;
		goto out;
	default:
		value = BADTOK;
		goto out;

	}
out:
	return value;
}

static uint64_t bus_batch_add_expr()
{
	int token;
	u64 value;
	value = bus_batch_mul_expr();
	while((token = bus_batch_mul_op()) != BADTOK) {
		if(token == ADD)
			value += bus_batch_mul_expr();
		if(token == SUB)
			value -= bus_batch_mul_expr();
	}
out:
	return value;
}

static void bus_batch_parser(char *string, int len, bus_arg_table_t *table)
{
	int nr_argc = 0;
	char *str;
	int toklen;
	if(!lexer_init(string, len)) {
		return;
	}

}